package com.fy.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fy.common.constants.KeysConstant;
import com.fy.mapper.ChatConstantMapper;
import com.fy.pojo.entity.ChatConstant;
import com.fy.service.ChatConstantService;
import com.fy.utils.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 智能客服常见问题服务实现类
 * 提供常见问题的缓存管理和查询服务
 *
 * @author fwq
 * @description 针对表【chatconstant(智能客服常见问题表)】的数据库操作Service实现
 * @createDate 2025-02-04 23:43:45
 */
@Slf4j
@Service
public class ChatConstantServiceImpl extends ServiceImpl<ChatConstantMapper, ChatConstant>
        implements ChatConstantService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public Result<List<String>> getQuestions() {
        try {
            // 1. 尝试从Redis获取所有问答数据
            List<Object> cachedData = redisTemplate.opsForHash()
                    .values(KeysConstant.CHAT_CONSTANT_REDIS_KEY);

            List<String> questions;

            if (cachedData.isEmpty()) {
                log.info("Redis缓存未命中，从数据库加载数据");
                // 2. 从数据库获取数据
                List<ChatConstant> chatConstants = baseMapper.selectList(null);

                // 3. 缓存到Redis
                chatConstants.forEach(item -> redisTemplate.opsForHash().put(
                        KeysConstant.CHAT_CONSTANT_REDIS_KEY,
                        item.getQuestion(), // 使用问题作为key
                        item // 存储整个对象
                ));

                // 4. 只提取问题列表
                questions = chatConstants.stream()
                        .map(ChatConstant::getQuestion)
                        .collect(Collectors.toList());

                log.info("成功缓存{}条数据到Redis", questions.size());
            } else {
                log.info("从Redis缓存获取数据");
                // 5. 获取所有Hash的key（即问题列表）
                questions = redisTemplate.opsForHash()
                        .keys(KeysConstant.CHAT_CONSTANT_REDIS_KEY)
                        .stream()
                        .map(Object::toString)
                        .collect(Collectors.toList());
            }

            // 6. 随机获取5条问题
            if (questions.size() > 5) {
                Collections.shuffle(questions);
                questions = questions.subList(0, 5);
            }

            log.info("返回{}个随机问题", questions.size());
            return Result.success(questions);

        } catch (Exception e) {
            log.error("获取常见问题列表失败", e);
            return Result.error("获取问题列表失败");
        }
    }

    /**
     * 根据问题获取答案
     * 优先从Redis缓存获取，如果未命中则从数据库查询并缓存
     *
     * @param question 问题内容
     * @return 答案内容
     */
    @Override
    public Result<String> getAnswer(String question) {
        try {
            // 1. 先从Redis缓存获取
            Object cachedData = redisTemplate.opsForHash()
                    .get(KeysConstant.CHAT_CONSTANT_REDIS_KEY, question);

            String answer;

            if (cachedData == null) {
                log.info("Redis缓存未命中，从数据库查询答案, 问题: {}", question);
                // 2. 缓存未命中，从数据库查询
                LambdaQueryWrapper<ChatConstant> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(ChatConstant::getQuestion, question);
                ChatConstant chatConstant = baseMapper.selectOne(queryWrapper);

                if (chatConstant == null) {
                    return Result.error("未找到该问题的答案");
                }

                // 3. 存入Redis缓存
                redisTemplate.opsForHash().put(
                        KeysConstant.CHAT_CONSTANT_REDIS_KEY,
                        question,
                        chatConstant);

                answer = chatConstant.getAnswer();
                log.info("已将问答数据缓存到Redis");
            } else {
                log.info("从Redis缓存获取答案");
                // 4. 从缓存数据中获取答案
                if (cachedData instanceof ChatConstant) {
                    answer = ((ChatConstant) cachedData).getAnswer();
                } else {
                    // 处理可能的序列化问题
                    ChatConstant chatConstant = JSONUtil.toBean(JSONUtil.toJsonStr(cachedData), ChatConstant.class);
                    answer = chatConstant.getAnswer();
                }
            }

            // 5. 更新访问次数
            updateViewCount(question);

            return Result.success(answer);

        } catch (Exception e) {
            log.error("获取答案失败, 问题: {}", question, e);
            return Result.error("获取答案失败");
        }
    }

    /**
     * 更新问题的访问次数
     */
    private void updateViewCount(String question) {
        try {
            Object cachedData = redisTemplate.opsForHash()
                    .get(KeysConstant.CHAT_CONSTANT_REDIS_KEY, question);

            if (cachedData != null) {
                ChatConstant chatConstant;
                if (cachedData instanceof ChatConstant) {
                    chatConstant = (ChatConstant) cachedData;
                } else {
                    chatConstant = JSONUtil.toBean(JSONUtil.toJsonStr(cachedData), ChatConstant.class);
                }

                chatConstant.setViewCount(chatConstant.getViewCount() + 1);

                // 更新Redis缓存
                redisTemplate.opsForHash().put(
                        KeysConstant.CHAT_CONSTANT_REDIS_KEY,
                        question,
                        chatConstant);

                // 异步更新数据库
                this.lambdaUpdate()
                        .eq(ChatConstant::getQuestion, question)
                        .setSql("view_count = view_count + 1")
                        .update();
            }
        } catch (Exception e) {
            log.error("更新访问次数失败, 问题: {}", question, e);
        }
    }
}
